from datetime import datetime
from inc.models import db, JiraReview, JiraProject, AdminMember, JiraApprovalStep, JiraReviewNode
from inc import logger
from sqlalchemy.exc import SQLAlchemyError


def get_approvals(user_id):
    """获取用户相关的审批列表（包括提交的和审批的）"""
    return JiraReview.query.filter(
        (JiraReview.submitter_id == user_id) |
        (JiraReview.reviewer_id == user_id)
    ).order_by(JiraReview.created_at.desc()).all()


def create_default_review_nodes():
    """创建默认的审批节点"""
    default_nodes = [
        {'description': '项目立项审批', 'order': 1},
        {'description': '项目预算审批', 'order': 2},
        {'description': '项目执行审批', 'order': 3},
        {'description': '项目结项审批', 'order': 4},
        {'description': '项目质量审批', 'order': 5}
    ]

    created_count = 0
    for node_data in default_nodes:
        existing_node = JiraReviewNode.query.filter_by(
            description=node_data['description']
        ).first()

        if not existing_node:
            new_node = JiraReviewNode(**node_data)
            db.session.add(new_node)
            created_count += 1
            logger.info(f"创建审批节点: {node_data['description']}")

    if created_count > 0:
        try:
            db.session.commit()
            logger.info(f"成功创建 {created_count} 个默认审批节点")
        except SQLAlchemyError as e:
            db.session.rollback()
            logger.error(f"创建默认审批节点失败: {str(e)}")

    return created_count


def get_default_review_node():
    """获取默认审批节点"""
    default_node = JiraReviewNode.query.order_by(JiraReviewNode.order).first()
    if not default_node:
        # 如果没有节点，创建一个
        default_node = JiraReviewNode(description='默认项目审批', order=1)
        db.session.add(default_node)
        db.session.commit()
        logger.info("创建默认审批节点")
    return default_node


def submit_approval(user_id, form_data):
    """提交新的审批请求"""
    project_id = form_data.get('project_id')
    notes = form_data.get('notes', '')

    # 查询项目
    project = JiraProject.query.get(project_id)
    if not project:
        raise ValueError("项目不存在")

    # 检查用户是否是项目成员
    if not any(member.member_id == user_id for member in project.members):
        raise PermissionError("非项目成员不能提交审批")

    # 获取审批流程的第一个步骤
    first_step = JiraApprovalStep.query.filter_by(
        flow_id=project.approval_flow_id,
        order=1
    ).first()

    if not first_step:
        raise ValueError("审批流程未配置第一个步骤")

    # 确定审批人 - 支持 project.first_approver_id 作为首审（流程外）
    if project.first_approver_id and project.first_approver_id != first_step.user_id:
        # 创建首审记录（step_id=None 表示首审）
        reviewer_id = project.first_approver_id
        step_id = None
    else:
        reviewer_id = project.first_approver_id if project.first_approver_id else first_step.user_id
        step_id = first_step.id

    # 记录调试信息
    logger.info(f"提交审批 - 项目ID: {project_id}, 流程ID: {project.approval_flow_id}")
    logger.info(f"第一步骤: 顺序{first_step.order}, 默认审批人ID: {first_step.user_id}")
    logger.info(f"项目第一审批人ID: {project.first_approver_id}, 最终审批人ID: {reviewer_id}, step_id={step_id}")

    # 获取默认节点
    default_node = get_default_review_node()

    # 创建审批记录
    approval = JiraReview(
        project_id=project_id,
        submitter_id=user_id,
        reviewer_id=reviewer_id,
        step_id=step_id,
        node_id=default_node.id,
        status='pending',
        notes=notes
    )

    try:
        db.session.add(approval)
        db.session.commit()
        logger.info(f"创建审批记录 {approval.id} 成功，审批人ID: {reviewer_id}，步骤ID: {step_id}")
        return approval
    except SQLAlchemyError as e:
        db.session.rollback()
        logger.error(f"创建审批记录失败: {str(e)}")
        raise ValueError("提交审批失败")


def review_approval(approval_id, user_id, action, notes):
    """处理审批"""
    approval = JiraReview.query.get(approval_id)
    if not approval:
        raise ValueError("审批记录不存在")

    project = JiraProject.query.get(approval.project_id)
    if not project:
        raise ValueError("关联项目不存在")

    # 权限检查
    if approval.reviewer_id != user_id:
        raise PermissionError("无权处理此审批")

    if approval.status != 'pending':
        raise ValueError("审批已处理")

    if action not in ('approve', 'reject'):
        raise ValueError("无效的操作")

    # 更新审批状态
    approval.status = 'approved' if action == 'approve' else 'rejected'
    approval.review_notes = notes
    approval.reviewed_at = datetime.now()

    # 处理 step_id 为 None 的首审情况：首审通过后，下一步应为流程中 order=1 的步骤
    if approval.step_id is None:
        logger.info(f"审批记录 {approval.id} 为首审记录 (step_id=None)")

        if action == 'approve':
            # 首审通过，查找流程中的第一个步骤 (order=1)
            first_step = JiraApprovalStep.query.filter_by(
                flow_id=project.approval_flow_id,
                order=1
            ).first()

            if not first_step:
                # 如果没有配置步骤，则直接将项目状态更新为“已批准”
                project.status = 'approved'
                project.reviewed_at = datetime.now()
                logger.warning(f"项目 {project.id} 在首审通过后，未找到审批流程的步骤 1，项目直接批准。")
            else:
                # 创建第 1 步的审批记录
                default_node = get_default_review_node()
                new_approval = JiraReview(
                    project_id=project.id,
                    submitter_id=approval.submitter_id,
                    reviewer_id=first_step.user_id,
                    step_id=first_step.id,  # 明确设置 step_id
                    node_id=default_node.id,
                    status='pending',
                    notes=approval.notes
                )
                db.session.add(new_approval)
                project.status = 'pending_review'
                logger.info(f"首审通过，创建第 1 步审批，审批人ID: {first_step.user_id}, 步骤ID: {first_step.id}")
        else:
            # 首审被驳回
            project.status = 'rejected'
            project.reviewed_at = datetime.now()
            logger.info(f"项目 {project.id} 首审被驳回。")

    else:
        # 原有流程处理（step_id 不为 None）
        if action == 'approve':
            # 获取当前步骤
            current_step = JiraApprovalStep.query.get(approval.step_id)
            if not current_step:
                raise ValueError(f"找不到审批步骤 {approval.step_id}")

            # 获取所有审批步骤并按顺序排序
            all_steps = JiraApprovalStep.query.filter_by(
                flow_id=project.approval_flow_id
            ).order_by(JiraApprovalStep.order).all()

            if not all_steps:
                raise ValueError("审批流程未配置步骤")

            logger.info(f"当前步骤: 第{current_step.order}步 - 审批人ID: {current_step.user_id}")
            logger.info(f"所有步骤: {[f'第{step.order}步(用户{step.user_id})' for step in all_steps]}")

            # 检查是否是最后一步
            if current_step.order == len(all_steps):
                # 所有步骤完成，批准项目
                project.status = 'approved'
                project.reviewed_at = datetime.now()
                logger.info(f"项目 {project.id} 已完成所有审批")
            else:
                # 查找下一步 - 优先查找 order+1
                next_step = None
                for step in all_steps:
                    if step.order == current_step.order + 1:
                        next_step = step
                        break

                if not next_step:
                    for step in all_steps:
                        if step.order > current_step.order:
                            next_step = step
                            break

                if next_step:
                    default_node = get_default_review_node()
                    logger.info(f"找到下一步: 第{next_step.order}步 - 审批人ID: {next_step.user_id}")
                    new_approval = JiraReview(
                        project_id=project.id,
                        submitter_id=approval.submitter_id,
                        reviewer_id=next_step.user_id,
                        step_id=next_step.id,
                        node_id=default_node.id,
                        status='pending',
                        notes=approval.notes
                    )
                    db.session.add(new_approval)
                    project.status = 'pending_review'
                    logger.info(f"创建下一步审批，审批人ID: {next_step.user_id}, 步骤顺序: {next_step.order}")
                else:
                    logger.warning(f"未找到项目{project.id}的下一步审批步骤")
        else:
            # 拒绝
            project.status = 'rejected'
            project.reviewed_at = datetime.now()

    try:
        db.session.commit()
        logger.info(f"审批 {approval.id} 处理成功")
        return approval
    except SQLAlchemyError as e:
        db.session.rollback()
        logger.error(f"审批处理失败: {str(e)}")
        raise ValueError("审批处理失败")


def get_review_list(user_id):
    """获取待我审批的列表"""
    # 获取所有待审批任务
    reviews = JiraReview.query.filter(
        JiraReview.status == 'pending',
        JiraReview.reviewer_id == user_id
    ).options(
        db.joinedload(JiraReview.project),
        db.joinedload(JiraReview.submitter)
    ).all()

    # 统一数据结构
    results = []
    for review in reviews:
        results.append({
            'id': review.id,
            'project': review.project,
            'submitter': review.submitter,
            'created_at': review.created_at,
            'status': review.status,
            'is_project': bool(review.project_id)
        })

    # 按时间排序
    return sorted(results, key=lambda x: x['created_at'], reverse=True)


def get_pending_approval_count(user_id):
    """获取待审批任务数量"""
    return JiraReview.query.filter_by(
        status='pending',
        reviewer_id=user_id
    ).count()


def get_approval_history(project_id):
    """获取项目的审批历史记录"""
    project = JiraProject.query.get_or_404(project_id)
    if not project.approval_flow:
        return []

    # 获取所有审批步骤的顺序映射
    steps_order_map = {
        step.id: step.order
        for step in project.approval_flow.steps
    }

    # 获取所有相关的审批记录，只筛选review_notes为"项目提交审核"的记录
    reviews = JiraReview.query.filter_by(
        project_id=project_id,
        notes="项目提交审核"
    ).all()

    history = []
    for review in reviews:
        step_order = None
        # 如果 review.step_id 存在，则从映射中获取 order
        if review.step_id:
            step_order = steps_order_map.get(review.step_id)
        # 如果 step_id 不存在，检查 review 的执行人是否为项目的第一审批人
        elif project.first_approver_id and review.reviewer_id == project.first_approver_id:
            step_order = 0

        # 添加 status_label 的定义
        status_labels = {
            'pending': '待处理',
            'approved': '已批准',
            'rejected': '已驳回'
        }
        status_label = status_labels.get(review.status, '未知状态')

        history.append({
            'step_order': step_order,
            'reviewer': review.reviewer,
            'status': review.status,
            'notes': review.review_notes,
            'reviewed_at': review.reviewed_at,
            'status_label': status_label
        })

    # 按步骤顺序排序，未知步骤放在最后
    return sorted(history, key=lambda x: (x['step_order'] is None, x['step_order']))


def fix_existing_approvals_node_id():
    """修复现有审批记录的 node_id"""
    # 查找所有 node_id 为 NULL 的审批记录
    broken_approvals = JiraReview.query.filter(
        JiraReview.node_id.is_(None)
    ).all()

    # 获取默认节点
    default_node = get_default_review_node()

    fixed_count = 0
    for approval in broken_approvals:
        approval.node_id = default_node.id
        fixed_count += 1
        logger.info(f"修复审批记录 {approval.id} 的 node_id 为 {default_node.id}")

    if fixed_count > 0:
        try:
            db.session.commit()
            logger.info(f"成功修复 {fixed_count} 条审批记录的 node_id")
        except SQLAlchemyError as e:
            db.session.rollback()
            logger.error(f"修复审批记录失败: {str(e)}")

    return fixed_count


# 初始化审批系统
def init_approval_system():
    """初始化审批系统数据"""
    try:
        # 创建默认审批节点
        node_count = create_default_review_nodes()

        # 修复现有数据
        fixed_count = fix_existing_approvals_node_id()

        logger.info(f"审批系统初始化完成: 创建{node_count}个节点, 修复{fixed_count}条记录")
    except Exception as e:
        logger.error(f"审批系统初始化失败: {str(e)}")

# 在应用启动时调用（可选）
# init_approval_system()